﻿
using Autodesk.Windows;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Windows.Input;

namespace AcadRibbon.Ribbons.Json;
/// <summary>
/// 命令绑定
/// </summary>
internal class ICommandConverter : JsonConverter<ICommand> {
    private readonly object[] commandProviders;

    public ICommandConverter(params object[] commandProviders) {
        this.commandProviders = commandProviders;
    }

    public override ICommand? ReadJson(JsonReader reader, Type objectType, ICommand? existingValue, bool hasExistingValue, JsonSerializer serializer) {
        if (reader.Path == RibbonCommandItem.CommandHandlerPropertyName) {
            string? commandName = reader.Value?.ToString();
            if (!string.IsNullOrEmpty(commandName)) {
                foreach (var commandProvider in commandProviders) {
                    var comProviderType = commandProvider.GetType();

                    //获取属性
                    var propInfo = comProviderType.GetProperties()
                         .Where(p => p.Name == commandName && typeof(ICommand)
                        .IsAssignableFrom(p.PropertyType))
                         .FirstOrDefault();
                    if (propInfo != null) {
                        return (ICommand)propInfo.GetValue(commandProvider);
                    }
                }

                return new ConverterCommandBase(
                    () => Acap.ShowAlertDialog($"没有找到命令名为{commandName}的命令"));
            }
        }
        return new ConverterCommandBase(
            () => Acap.ShowAlertDialog($"未绑定命令命令"));
    }

    public override void WriteJson(JsonWriter writer, ICommand? value, JsonSerializer serializer) {
        throw new NotImplementedException();
    }
    /// <summary>
    /// 命令交互基础类
    /// </summary>
    private class ConverterCommandBase : System.Windows.Input.ICommand {
        private readonly Action doExecute;

        public event EventHandler? CanExecuteChanged;
        public ConverterCommandBase(Action doExecute) {
            this.doExecute = doExecute;
        }
        /// <summary>
        /// 是否可执行，通用方法，传入委托
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public bool CanExecute(object parameter) {
            return true;
        }
        /// <summary>
        /// 执行
        /// </summary>
        /// <param name="parameter"></param>
        public void Execute(object parameter) {
            doExecute.Invoke();
        }
    }
}